﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;

namespace FasterWPF
{
    public enum ComboStyles
    {
       NoTypeAheadButSelectableText = 1,
       TypeAheadButCannotSelectOrCopyText = 2, 
       TypeAheadSelectableButAcceptsAnyText = 3
    }

    public class ComboBoxArgs
    {
        public int SearchTextX
        {
            get;
            set;
        }

        public int SearchTextY
        {
            get;
            set;
        }

        public ComboBoxArgs(int searchTextX, int searchTextY)
        {
            SearchTextX = searchTextX;
            SearchTextY = searchTextY;
        }
    }

    public class ComboBoxParent : FasterWPF.IParent, IScrollViewerStrategy
    {         
        //this is ANA?
        public object Generate<T>(object chain, T args, Action<ContentControl> addUIElementsAction)
        {
            return chain;
        }

        #region IParent

        //this is BIND
        public object Add<T>(object chain, string key, T args, Border itemToAdd)
        {
            int searchX = 0; //default to zero
            int searchY = 0; //default to zero
            ComboBoxArgs defaultArgs = new ComboBoxArgs(searchX, searchY);

            if (args is ComboBoxArgs)
            {
                //allow overriding defaults
                searchX = (args as ComboBoxArgs).SearchTextX;
                searchY = (args as ComboBoxArgs).SearchTextY;
                defaultArgs.SearchTextX = searchX;
                defaultArgs.SearchTextY = searchY; 
            }

            ((ComboBox)chain).StoreSetting<ComboBox>("ComboBoxArgs" + key, defaultArgs);

            ((ComboBox)chain).GetSetting<ComboBox, ObservableCollection<Border>>("ObsCol").Add(itemToAdd);
                   
            //set these here to allow overriding the default values
            ScrollViewerExt.SetCanContentScroll<FrameworkElement>((FrameworkElement)chain);
            //ScrollViewerExt.SetVerticalPageUpButtonDelayAndInterval<FrameworkElement>((FrameworkElement)chain);

            var collection = ((ComboBox)chain).GetSetting<ComboBox, ObservableCollection<Border>>("ObsCol");

            if (((ComboBox)chain).ItemsSource != collection)
            {
                ((ComboBox)chain).DataContext = collection;
                ((ComboBox)chain).ItemsSource = collection;
            }

            //Leverage the ToolTip for binding to the TextSearch.Text property to enable Type-ahead
            ((Border)itemToAdd).ToolTip = ((Border)itemToAdd).GetText<ComboBox>(searchX, searchY).ToString();            
            (((Border)itemToAdd)).SetBinding(TextSearch.TextProperty, "ToolTip");
            
            return chain;
        }

        public void Remove(object chain, string key, Border itemToRemove)
        {
            Dictionary<string, object> settingsDict =((ComboBox)chain).GetSettingsDictionary<ComboBox>();
            settingsDict.Remove("ComboBoxArgs" + key);

            ((ComboBox)chain).GetSetting<ComboBox, ObservableCollection<Border>>("ObsCol").Remove(itemToRemove); //remove from ComboBox

            IComposite ic = (IComposite)(((ComboBox)chain).GetIComposite<ComboBox>());
            ic.RemoveFromChain(itemToRemove);
        }

        public Dictionary<string, object> RetrieveDictionary(object chain)
        {
            return ((ComboBox)chain).GetCompositeLookupDictionary<ComboBox>();
        }

        //this is CATA?
        public List<Border> RetrieveCollection(object chain)
        {
            ObservableCollection<Border> comboBoxItems = ((ComboBox)chain).GetSetting<ComboBox, ObservableCollection<Border>>("ObsCol");
            return comboBoxItems.ToList<Border>();
        }

        #endregion

        #region ICanSort

        public void ClearCollection(object chain)
        {
        }

        public void BeforeSortCollection<T>(object chain, object args, int row, int column, FasterWPF.CommonExt.SortOrder sortOrder)
                  where T : FrameworkElement
        { }

        public void BeforeSortCollection1Then2<T>(object chain, object args, int row, int column, int row2, int column2, FasterWPF.CommonExt.SortOrder sortOrder, FasterWPF.CommonExt.SortOrder sortOrder2)
  where T : FrameworkElement
        { }

        public void AfterSortCollection<T>(object chain)
               where T : FrameworkElement
        { }

        public void InnerSortCollection(object chain, int row, int column, string key, ref int counter, Border itemToReAdd)
        {
            //Hmm, record original order in which they were added?

            //re-add in new pattern of x-y coordinates, making sure to NULL-check?!?  Maybe pass new order on Settings Dictionary?

            throw new NotImplementedException();
        }

        #endregion

        #region ICanSelect

        public void SetSelected(object chain, Border itemToSetAsSelected)
        {
        }

        #endregion

        #region IScrollViewerStrategy

        public ScrollViewer GetScrollViewer(object chain)
        {
            ComboBox lbx = (ComboBox)chain;
            var builtCheck = lbx.ApplyTemplate();
            Border bd = (Border)lbx.Template.FindName("DropDownBorder", lbx);

            var settings = lbx.GetSettingsDictionary();

            if (settings.Keys.Contains("ScrollViewerPadding"))
            {
                bd.Padding = (Thickness)settings["ScrollViewerPadding"];
            }
            else
            {
                bd.Padding = new Thickness(0); //default to zero
            }
            ScrollViewer svw = bd.Child.Cast<ScrollViewer>();

            return svw;
        }

        public T GetParentContainerFromScrollViewerThumb<T>(System.Windows.Controls.Primitives.Thumb myThumb)
        {
            T source = ((Border)((ScrollViewer)
                ((Grid)
                ((ScrollBar)myThumb.TemplatedParent).Parent).TemplatedParent
                ).Parent).TemplatedParent.Cast<T>();
            return source;
        }

        #endregion
    }
}
